import React, { useEffect, useRef, useState } from "react";
import "./index.scss";
import { Button, Empty, Dropdown, MenuProps, message } from 'antd';
import { DownOutlined } from "@ant-design/icons";
import useLocalStore from "@/store/local";
import { getUserInfo, createDialog, getChatList, fetchChat } from "@/api/modules/gpt";
import { Gpt, Pager, Result } from "@/api/interface";
import MoreDrawer from "./components/MoreDrawer";
import ModalLogin from "./components/ModalLogin";
import SiderRobot from "./components/SiderRobot";
import { ItemType } from "antd/es/menu/interface";
import BackBottom from "./components/BackBottom";
import Message from "./components/Message";
import SendInput from "./components/SendInput";
import { debounce, isPc, throttle } from "@/utils";
import { fetchEventSource } from "@microsoft/fetch-event-source";
console.log("你好");

const ROBOT_IMG = "https://bucket-chabaidao-1308160773.cos.ap-guangzhou.myqcloud.com/img%2Frobot.png"
let isFinished = false;
let lastScrollTop = 0;
let isUserScroll = false;

console.log("%c林深时见鹿，海深时见鲸，情深时见你🥰")
const Page: React.FC = () => {
    const { token } = useLocalStore();
    const loginRef: any = useRef();
    const moreDrawerRef: any = useRef();
    const gunRef: any = useRef(null);
    const [userInfo, setUserInfo] = useState<Gpt.UserInfo>()
    const [chatMessage, setChatMessage] = useState<{ list: Gpt.Message[] } & Pager>()
    const [avtiveDialogTitle, setActiveDialogTitle] = useState("") //当前活跃的会话标题
    const [dialogList, setDialogList] = useState<ItemType[]>() //会话列表的下拉菜单
    const [isOnInput, setOnIput] = useState(false)
    const [isShow, setIsShow] = useState(false)
    const [innerHeight, setInnerHeight] = useState(window.innerHeight)


    useEffect(() => {
        onLogin()
    }, [])


    window.onresize = debounce(() => setInnerHeight(window.innerHeight))
    const menu = [
        {
            label: '回答',
            key: 0,
        },
        {
            label: '文本翻译',
            key: 1,
        },
        {
            label: '文本纠错',
            key: 2,
        },
        {
            label: '生成图片',
            key: 3,
        },
        {
            label: '文字转语音',
            key: 4,
        },
        {
            label: '语音转文字',
            key: 5,
        },
        {
            label: '图片想象',
            key: 6,
        },
    ];

    const onLogin = async () => {
        if (token) {
            try {
                const { data } = await getUserInfo()
                if (!data.last_dialog_id) {
                    const { data: { message, list, ...assets } } = await createDialog()
                    setChatMessage({ list: [message], ...assets })
                    data.last_dialog_id = list[0]._id
                }
                setUserInfo(data)
            } catch (error) {
                loginRef.current?.setIsModalOpen(true)
            }
        } else {
            loginRef.current?.setIsModalOpen(true)
        }
    }
    const onSend = async (content: string, type = 0, file?: { url: string, key: string, fileType: string }) => {

        if (type === 0) {
            // 用户提问
            setChatMessage(pre => ({
                ...pre!,
                total: pre!.total + 2,
                list: [...pre!.list, { content: content, role: "user", date: Date.now(), avatar: userInfo!.avatar }, { content: "", role: "assistant", date: Date.now() + 1, avatar: ROBOT_IMG }]
            }))
        } else if (type === 1) {
            // 用户编辑
            setChatMessage(pre => ({
                ...pre!,
                list: [...pre!.list.slice(0, -1), { content: "", role: "assistant", date: Date.now() + 1, avatar: ROBOT_IMG }]
            }))
        } else if (type === 2) {
            // 重新回答
            setChatMessage(pre => ({
                ...pre!,
                total: pre!.total + 1,
                list: [...pre!.list.slice(0, -1), { ...pre!.list[pre!.list.length - 1], is_revocation: true }, { content: "", role: "assistant", date: Date.now() + 1, avatar: ROBOT_IMG }]
            }))
        } else if (type === 3 && file) {
            // 伴随文件询问
            setChatMessage(pre => ({
                ...pre!,
                total: pre!.total + 2,
                list: [...pre!.list, { content: content, role: "user", date: Date.now(), avatar: userInfo!.avatar, prompt: { type: file.fileType, content: file.url } }, { content: "", role: "assistant", date: Date.now() + 1, avatar: ROBOT_IMG }]
            }))

        }
        setTimeout(() => {
            onScrollToBottom("instant")
        });
        setOnIput(true)
        processStream({ message: content, dialog_id: userInfo!.last_dialog_id, type }, file)
    }
    const onRetryMsg = () => {
        const _list = [...chatMessage!.list].reverse()
        for (let i = 0; i < _list.length; i++) {
            if (_list[i].role == "user") {
                console.log(_list[i].content);
                onSend(_list[i].content, 2)
                return
            }
        }
    }

    const processStream = async (data: Gpt.Chat, file?: { url: string, key: string, fileType: string }) => {
        const controller = new AbortController()
        const signal = controller.signal;
        let lastMessage = ""
        let timer: NodeJS.Timeout
        fetchEventSource(`${import.meta.env.VITE_XTIGER_YRL}/trial/gpt/stream`, {
            method: "POST",
            headers: { "Content-Type": "application/json", token },
            signal,

            openWhenHidden: true,
            body: JSON.stringify({ message: data.message, dialog_id: userInfo!.last_dialog_id, type: data.type, file }),
            onmessage: (event) => {
                const data = JSON.parse(event.data)

                if (data.event === "text") {
                    lastMessage += data.message;
                    // timer && clearInterval(timer)
                    // timer = setInterval(() => {
                    //     console.log("触发");
                        
                        setChatMessage(pre => ({
                            ...pre!,
                            list: [...pre!.list.slice(0, -1), { ...pre!.list[pre!.list.length - 1], content: lastMessage }]
                        }));
                        onScrollToBottom("instant")
                    // }, 50)


                } else if (data.event == "end") {
                    // setChatMessage(pre => ({
                    //     ...pre!,
                    //     list: [...pre!.list.slice(0, -1), { ...pre!.list[pre!.list.length - 1], content: lastMessage }]
                    // }));
                    // clearInterval(timer)
                    setOnIput(false)
                    onScrollToBottom("instant")
                    controller.abort();
                }
            },
            onclose: () => {
                console.log("后端关闭");
                // setChatMessage(pre => ({
                //     ...pre!,
                //     list: [...pre!.list.slice(0, -1), { ...pre!.list[pre!.list.length - 1], content: lastMessage }]
                // }));
                // clearInterval(timer)
                onScrollToBottom("instant")
                setOnIput(false)
                controller.abort();
            },
            onerror(err) {
                // setChatMessage(pre => ({
                //     ...pre!,
                //     list: [...pre!.list.slice(0, -1), { ...pre!.list[pre!.list.length - 1], content: lastMessage }]
                // }));
                // clearInterval(timer)
                console.log("报错啦", err);
                setOnIput(false)
                controller.abort();
                throw err;    //必须throw才能停止 
            }
        })


    }

    // 接收当前选中的会话活跃项
    const onDialogOpt = async (item: Gpt.DialogItem) => {

        setDialogList(moreDrawerRef.current?.chatList?.list?.map((item: Gpt.DialogItem) => ({
            label: item.title,
            key: item._id
        })))

        setActiveDialogTitle(item.title)
        if (item._id !== userInfo?.last_dialog_id) {
            setUserInfo({ ...userInfo!, last_dialog_id: item._id })
        }
        // 获取聊天记录
        const { data } = await getChatList({ id: item._id })
        data.list.reverse()
        setChatMessage(data)
        isFinished = false
        setTimeout(() => {
            onScrollToBottom("instant")
        });

    }
    // 聊天窗口顶部会话标题点击
    const onTitleClick: MenuProps['onClick'] = ({ key }) => {
        const findItem = moreDrawerRef.current?.chatList?.list?.find((item: Gpt.DialogItem) => item?._id == key)
        console.log("迪此次：", findItem._id);

        onDialogOpt(findItem)

    };

    const onCreateDialog = async () => {
        const { data: { message, list, ...assets } } = await createDialog()
        setChatMessage({ list: [message], ...assets })
        setUserInfo({ ...userInfo!, last_dialog_id: list[0]._id })
        moreDrawerRef.current?.setDrawerOpen(false)
    }

    const onStop = () => {
        chatMessage!.list[chatMessage!.list.length - 1].controller?.abort()
        setOnIput(false)
    }
    const onScrollToBottom = (behavior: "smooth" | "instant" | "auto" = "smooth") => {
        !isUserScroll && gunRef.current?.lastElementChild?.scrollIntoView({ behavior, block: "end" })
    }
    const onScroll = async () => {
        const { scrollTop, scrollHeight, clientHeight } = gunRef.current
        isUserScroll = scrollTop < lastScrollTop
        lastScrollTop = scrollTop
        if (scrollTop + clientHeight + 10 >= scrollHeight) {
            console.log("到底部");
            setIsShow(false)
        } else {
            if (scrollTop <= 0) {
                console.log("到顶部");
                isFinished = chatMessage!.list.length >= chatMessage!.total
                if (isFinished) {
                    return
                } else {
                    const { data } = await getChatList({ id: userInfo!.last_dialog_id, page: chatMessage!.page + 1 })
                    data.list.reverse()

                    const scrollPosition = gunRef.current.scrollHeight;
                    setChatMessage(pre => ({
                        ...data,
                        list: data.list.concat(pre!.list),
                    }))
                    gunRef.current.scrollTop = gunRef.current.scrollHeight - scrollPosition;

                }
            }
            setIsShow(true)
        }
    }

    return (
        <>
            <div className="only_gpt flex-start" style={{ height: innerHeight - 30 }}>
                {userInfo && <MoreDrawer ref={moreDrawerRef} userInfo={userInfo} onDialogOpt={onDialogOpt} onCreateDialog={onCreateDialog} />}
                <>
                    {isPc() && <SiderRobot />}
                    <main>
                        <div className="chat_detail">
                            {chatMessage?.list.length ?
                                <>
                                    <Dropdown menu={{ onClick: onTitleClick, items: dialogList }}>
                                        <h3 className="chat_title flex-center">
                                            <p>{avtiveDialogTitle}</p>
                                            <DownOutlined />
                                        </h3>
                                    </Dropdown>

                                    <ul onScroll={onScroll} ref={gunRef} className="gun_wrap">
                                        {chatMessage.list.map((item, index) => <li key={index} style={{ display: "flex", flexDirection: item.role === 'user' ? 'row' : 'row-reverse' }}>
                                            <Message
                                                curIndex={index}
                                                chatMessage={chatMessage}
                                                onRetryMsg={onRetryMsg}
                                                onEditMsg={_content => onSend(_content, 1)}
                                                isOnInput={isOnInput}
                                            />
                                        </li>)}

                                    </ul>

                                </>
                                : <Empty description="我什么都知道" />}</div>

                        <SendInput isOnInput={isOnInput} onSend={(content, file) => onSend(content, file ? 3 : 0, file)} />
                        <BackBottom isShow={isShow} onClick={() => { isUserScroll = false, onScrollToBottom() }} />
                    </main>
                </ >
                {isOnInput && <div style={{ position: "fixed", bottom: "140px", left: "50%", transform: "translateX(-50%)" }}> {<Button type="primary" onClick={onStop}>停止回答</Button>}</div>}
                <ModalLogin ref={loginRef} onLogin={onLogin} />
            </div >
            <footer className="link_footer"><a href="https://beian.miit.gov.cn/" target="_blank">鄂ICP备2024067443号-1</a></footer>

        </>
    );
};

export default Page;
